home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / semaphores / src / obtainsemaphoreshared.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  2.3 KB  |  101 lines

  1. /*
  2.     $Id$
  3.     $Log$
  4.     Desc:
  5.     Lang: english
  6. */
  7. #include "exec_intern.h"
  8. #include "semaphores.h"
  9.  
  10. /*****************************************************************************
  11.  
  12.     NAME */
  13.     #include <exec/semaphores.h>
  14.     #include <clib/exec_protos.h>
  15.  
  16.     __AROS_LH1(void, ObtainSemaphoreShared,
  17.  
  18. /*  SYNOPSIS */
  19.     __AROS_LA(struct SignalSemaphore *, sigSem, A0),
  20.  
  21. /*  LOCATION */
  22.     struct ExecBase *, SysBase, 113, Exec)
  23.  
  24. /*  FUNCTION
  25.     Get a shared lock on a semaphore. If the lock cannot be obtained
  26.     immediately this function waits. There may be more than one shared
  27.     locks at the same time but only one exclusive one. An exclusive
  28.     lock prevents shared locks. Shared locks are released with
  29.     ReleaseSemaphore().
  30.  
  31.     INPUTS
  32.     sigSem - Pointer to semaphore structure
  33.  
  34.     RESULT
  35.  
  36.     NOTES
  37.     This function preserves all registers.
  38.  
  39.     EXAMPLE
  40.  
  41.     BUGS
  42.  
  43.     SEE ALSO
  44.     ReleaseSemaphore()
  45.  
  46.     INTERNALS
  47.  
  48.     HISTORY
  49.     29-10-95    digulla automatically created from
  50.                 exec_lib.fd and clib/exec_protos.h
  51.     21-01-96    fleischer implementation
  52.  
  53. *****************************************************************************/
  54. {
  55.     __AROS_FUNC_INIT
  56.     __AROS_BASE_EXT_DECL(struct ExecBase *,SysBase)
  57.     struct Task *me;
  58.  
  59.     /* Get pointer to current task */
  60.     me=SysBase->ThisTask;
  61.  
  62.     /* Arbitrate for the semaphore structure */
  63.     Forbid();
  64.  
  65.     /* Check if there's an exclusive lock on the semaphore */
  66.     if(sigSem->ss_NestCount>0)
  67.     {
  68.     /* Yes. Is it owned by the current task? */
  69.     if(sigSem->ss_Owner!=me)
  70.     {
  71.         /* No. Prepare a node for the waiting queue. */
  72.         struct SemaphoreNode sn;
  73.         sn.node.ln_Pri =SN_TYPE_OBTAIN;
  74.         sn.node.ln_Name=(char *)SM_SHARED;
  75.         sn.task       =me;
  76.  
  77.         /* Add it. */
  78.         AddTail((struct List *)&sigSem->ss_WaitQueue,&sn.node);
  79.  
  80.         /* Wait until the semaphore is free */
  81.         Wait(SEMAPHORESIGF);
  82.  
  83.         /* ss_NestCount and ss_Owner are already set by ReleaseSemaphore() */
  84.     }else
  85.         /* Add one nesting level more */
  86.         sigSem->ss_NestCount++;
  87.     }else
  88.     {
  89.     /* There's no exclusive lock on the semaphore. Get a shared one. */
  90.     sigSem->ss_NestCount--;
  91.  
  92.     /* Invalidate the owner field - so no task may think this semaphore is his. */
  93.     sigSem->ss_Owner=NULL;
  94.     }
  95.  
  96.     /* All done. */
  97.     Permit();
  98.     __AROS_FUNC_EXIT
  99. } /* ObtainSemaphoreShared */
  100.  
  101.